package com.fivestar.pmanager.core.base;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fivestar.pmanager.core.serializer.JsonDateSerializer;
import com.fivestar.pmanager.core.util.ErrorMsgHelper;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@SuppressWarnings("serial")
public class BaseBean implements Serializable
{
    public static final String SORT_BY_ASC = "ASC";
    public static final String SORT_BY_DESC = "DESC";

    public static final String FLAG_GREATER = ">";
    public static final String FLAG_LESS = "<";
    
    protected static final Logger LOG = Logger.getLogger(BaseBean.class);
    

    /**
     * numbers for per page
     * 偏移量
     */
    protected int offset;
    protected int startIndex;

    /**
     * sorting field for sorting
     */
    protected String sortField;

    /**
     * sorting order for sorting. eg asc or desc
     */
    protected String sortBy;

    /**
     * index of record, use to display line number
     */
    protected int rowIndex;
    
    // 主键
    protected Integer rowId;
    // 创建人
    protected Integer createBy;
    // 创建时间
    @JsonSerialize(using = JsonDateSerializer.class)
    protected Date createTime;
    // 更新人
    protected Integer modifyBy;
    // 更新时间
    @JsonSerialize(using = JsonDateSerializer.class)
    protected Date modifyTime;
    // 删除标志
    protected String isDeleted;
    // 修改次数
    protected Integer modifyNum;
    
    protected Integer orderId;

    protected String oldUpdDate;
    
    protected String createByName;//创建人名称

    //app前端列表刷新、加载
    protected Integer pidt;	        //刷新序列
    protected String ptarget;		//刷新类型
    protected Integer pnum;         //请求条数

    public BaseBean()
    {

    }


    public void initBeforeCreate(int actor)
    {
        Date currDate = new Date();
        setCreateBy(actor);
        setCreateTime(currDate);
        setModifyBy(actor);
        setModifyTime(currDate);
        setModifyNum(0);
        setIsDeleted("0");
    }

    public void initBeforeUpdate(int actor)
    {
        Date currDate = new Date();
        setModifyBy(actor);
        setModifyTime(currDate);

    }

    public void initBeforeDelete(int actor)
    {
        Date currDate = new Date();
        setModifyBy(actor);
        setModifyTime(currDate);
        setIsDeleted("1");
    }

    public String toString()
    {
        try
        {
            return BeanUtils.describe(this).toString();
        }
        catch (Exception exception)
        {
            return exception.getMessage();
        }
    }


    public int hashCode()
    {
        return toString().hashCode();
    }


    /*
     * trim string
     */
    public void trimAllString() throws Exception
    {
        Method[] methods = this.getClass().getMethods();
        if (methods != null && methods.length > 0)
        {
            for (int i = 0; i < methods.length; i++)
            {
                Method method = methods[i];
                if (method.getName().startsWith("get"))
                {
                    Object resultObj = method.invoke(this, new Object[] {});
                    if (resultObj != null && resultObj instanceof String)
                    {
                        String resultStr = (String) resultObj;
                        String setMethodName = "set"
                                + method.getName().substring(3,
                                        method.getName().length());

                        try
                        {
                            Method setMethod = this.getClass()
                                    .getMethod(setMethodName,
                                            new Class[] { String.class });
                            setMethod.invoke(this,
                                    new Object[] { resultStr.trim() });
                        }
                        catch (NoSuchMethodException e)
                        {
                            ErrorMsgHelper.logError(LOG, getClass().getName(),
                                    e);
                        }
                    }
                }
            }
        }
    }


    public void setAllEmptyStringToNull() throws Exception
    {
        Method[] methods = this.getClass().getMethods();
        if (methods != null && methods.length > 0)
        {
            for (int i = 0; i < methods.length; i++)
            {
                Method method = methods[i];
                if (method.getName().startsWith("get"))
                {
                    Object resultObj = method.invoke(this, new Object[] {});
                    if (resultObj instanceof String)
                    {
                        String result = (String) resultObj;
                        if ("".equals(result.trim()))
                        {
                            String setMethodName = "set"
                                    + method.getName().substring(3,
                                            method.getName().length());
                            try
                            {
                                Method setMethod = this.getClass().getMethod(
                                        setMethodName,
                                        new Class[] { String.class });
                                setMethod.invoke(this, new Object[] { null });
                            }
                            catch (NoSuchMethodException e)
                            {
                                ErrorMsgHelper.logError(LOG, getClass()
                                        .getName(), e);
                            }
                        }
                    }
                }
            }
        }
    }


    public Map<String, Object> toMapValues()
    {
        Map<String, Object> rlt = new HashMap<String, Object>();

        Method[] methods = this.getClass().getDeclaredMethods();
        if (methods == null || methods.length == 0)
        {
            return rlt;
        }

        for (Method method : methods)
        {
            if (!Modifier.isPublic(method.getModifiers()))
            {
                continue;
            }

            if (!method.getName().startsWith("get"))
            {
                continue;
            }

            Object resultObj = null;

            try
            {
                resultObj = method.invoke(this, new Object[] {});
            }
            catch (Exception e)
            {
                ErrorMsgHelper.logError(LOG, getClass().getName(), e);
                continue;
            }

            char[] array = method.getName().substring(3).toCharArray();
            StringBuffer sb = new StringBuffer();

            for (char c : array)
            {
                if (Character.isUpperCase(c))
                {
                    sb.append('_');
                    sb.append(c);
                }
                else
                {
                    sb.append(Character.toUpperCase(c));
                }
            }

            String key = sb.toString();

            if (key.startsWith("_"))
            {
                key = key.substring(1);
            }

            if (resultObj instanceof Enum<?>)
            {
                resultObj = resultObj.toString();
            }

            rlt.put(key, resultObj);
        }

        return rlt;
    }

    public String getSortField()
    {
        return sortField;
    }


    public void setSortField(String sortField)
    {
        this.sortField = sortField;
    }


    public String getSortBy()
    {
        return sortBy;
    }


    public void setSortBy(String sortBy)
    {
        this.sortBy = sortBy;
    }

    public Integer getRowId()
    {
        return rowId;
    }


    public void setRowId(Integer rowId)
    {
        this.rowId = rowId;
    }



    public Date getCreateTime()
    {
        return createTime;
    }


    public void setCreateTime(Date createTime)
    {
        this.createTime = createTime;
    }

    public Date getModifyTime()
    {
        return modifyTime;
    }


    public void setModifyTime(Date modifyTime)
    {
        this.modifyTime = modifyTime;
    }


    public String getIsDeleted()
    {
        return isDeleted;
    }


    public void setIsDeleted(String isDeleted)
    {
        this.isDeleted = isDeleted;
    }


    public String getOldUpdDate()
    {
        return oldUpdDate;
    }


    public void setOldUpdDate(String oldUpdDate)
    {
        this.oldUpdDate = oldUpdDate;
    }


    /**
     * @return Returns the modifyNum.
     */
    public Integer getModifyNum()
    {
        return modifyNum;
    }


    /**
     * @param modifyNum The modifyNum to set.
     */
    public void setModifyNum(Integer modifyNum)
    {
        this.modifyNum = modifyNum;
    }


    /**
     * @return Returns the offset.
     */
    public int getOffset()
    {
        return offset;
    }


    /**
     * @param offset The offset to set.
     */
    public void setOffset(int offset)
    {
        this.offset = offset;
    }


    /**
     * @return Returns the rowIndex.
     */
    public int getRowIndex()
    {
        return rowIndex;
    }


    /**
     * @param rowIndex The rowIndex to set.
     */
    public void setRowIndex(int rowIndex)
    {
        this.rowIndex = rowIndex;
    }


    /**
     * @return Returns the createBy.
     */
    public Integer getCreateBy()
    {
        return createBy;
    }


    /**
     * @param createBy The createBy to set.
     */
    public void setCreateBy(Integer createBy)
    {
        this.createBy = createBy;
    }


    /**
     * @return Returns the modifyBy.
     */
    public Integer getModifyBy()
    {
        return modifyBy;
    }


    /**
     * @param modifyBy The modifyBy to set.
     */
    public void setModifyBy(Integer modifyBy)
    {
        this.modifyBy = modifyBy;
    }


    /**
     * @return Returns the createByName.
     */
    public String getCreateByName()
    {
        return createByName;
    }


    /**
     * @param createByName The createByName to set.
     */
    public void setCreateByName(String createByName)
    {
        this.createByName = createByName;
    }


    /**
     * @return Returns the orderId.
     */
    public Integer getOrderId()
    {
        return orderId;
    }


    /**
     * @param orderId The orderId to set.
     */
    public void setOrderId(Integer orderId)
    {
        this.orderId = orderId;
    }


    public int getStartIndex()
    {
        return startIndex;
    }


    public void setStartIndex(int startIndex)
    {
        this.startIndex = startIndex;
    }

    public Integer getPidt() {
        return pidt;
    }

    public void setPidt(Integer pidt) {
        this.pidt = pidt;
    }

    public String getPtarget() {
        return ptarget;
    }

    public void setPtarget(String ptarget) {
        this.ptarget = ptarget;
    }

    public Integer getPnum() {
        return pnum;
    }

    public void setPnum(Integer pnum) {
        this.pnum = pnum;
    }
    
}

